<template>
  <div class="login">
    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
      <h3 class="title">登 录</h3>
      <div class="login_header">
        <a :class="{active:loginForm.type === 'password'}" style="margin: 50px;" @click="loginForm.type = 'password'">密码登录</a>
        <a :class="{active:loginForm.type === 'code'}" style="margin: 50px;" @click="loginForm.type = 'code'">短信登录</a>
      </div>

      <div v-show="loginForm.type === 'password'">
        <el-form-item prop="username">
          <el-input
            ref="username"
            v-model="loginForm.username"
            type="text"
            placeholder="手机号/邮箱/账号"
            tabindex="1"
            auto-complete="off"
          >
            <template v-slot:prefix>
              <svg-icon icon-class="user" class="el-input__icon input-icon" />
            </template>
          </el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input
            :key="passwordType"
            ref="password"
            v-model="loginForm.password"
            :type="passwordType"
            placeholder="密码"
            tabindex="2"
            auto-complete="off"
            @keyup.enter.native="handleLogin"
          >
            <template v-slot:prefix>
              <svg-icon icon-class="password" class="el-input__icon input-icon" />
            </template>
            <template v-slot:suffix>
              <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" class="el-input__icon input-icon" @click="handleShowPwd" />
            </template>
          </el-input>
        </el-form-item>
        <el-form-item prop="captcha">
          <el-input
            v-model="loginForm.captcha"
            placeholder="验证码"
            style="width: 63%"
            tabindex="3"
            auto-complete="off"
            @keyup.enter.native="handleLogin"
          >
            <template v-slot:prefix>
              <svg-icon icon-class="safety-certificate" class="el-input__icon input-icon" />
            </template>
          </el-input>
          <div class="login-code">
            <img :src="codeUrl" class="login-code-img" @click="handleCaptcha">
          </div>
        </el-form-item>
        <el-checkbox v-model="loginForm.rememberMe" style="margin:0 0 25px 0;">记住密码</el-checkbox>
      </div>

      <div v-show="loginForm.type === 'code'">
        <el-form-item prop="mobile">
          <el-input
            ref="mobile"
            v-model="loginForm.mobile"
            type="text"
            placeholder="手机号"
            tabindex="1"
            auto-complete="off"
          >
            <template v-slot:prefix>
              <svg-icon icon-class="mobile" class="el-input__icon input-icon" />
            </template>
          </el-input>
        </el-form-item>
        <el-form-item prop="code">
          <el-input
            v-model="loginForm.code"
            placeholder="验证码"
            style="width: 63%"
            tabindex="2"
            auto-complete="off"
            @keyup.enter.native="handleLogin"
          >
            <template v-slot:prefix>
              <svg-icon icon-class="safety-certificate" class="el-input__icon input-icon" />
            </template>
          </el-input>
          <div class="login-code">
            <el-button
              :loading="sending"
              :disabled="sendDisabled"
              size="small"
              type="primary"
              style="width:100%;"
              @click="handleSendSms"
            >
              {{ sendButtonText }}
            </el-button>
          </div>
        </el-form-item>
        <div style="height: 20px;" />
      </div>

      <el-form-item style="width:100%;">
        <el-button
          :loading="loading"
          size="medium"
          type="primary"
          style="width:100%;"
          @click.native.prevent="handleLogin"
        >
          <span v-if="!loading">登录</span>
          <span v-else>登 录 中...</span>
        </el-button>
        <div style="float: right;">
          <router-link class="link-type" :to="'/register'">没有账号？立即注册</router-link>
        </div>
      </el-form-item>
    </el-form>
    <!--  底部  -->
    <div class="el-login-footer">
      <span>Copyright © 2018-2024 flying All Rights Reserved.</span>
    </div>
  </div>
</template>

<script>
// import { encrypt, decrypt } from '@/utils/jsencrypt'

import { validMobile } from '@/utils/validate'
import Cookies from 'js-cookie'
import axios from 'axios'
import { v4 as UUIDv4 } from 'uuid'
import moment from 'moment'
import { sendCode } from '@/api/user'
moment.suppressDeprecationWarnings = true

export default {
  name: 'Login',
  // components: {  },
  data() {
    const validateMobile = (rule, value, callback) => {
      if (!validMobile(value)) {
        callback(new Error('请输入正确的手机号'))
      } else {
        callback()
      }
    }
    const validatePassword = (rule, value, callback) => {
      if (value.length < 6) {
        callback(new Error('密码至少6个字符'))
      } else {
        callback()
      }
    }
    return {
      codeUrl: '',
      loginForm: {
        username: '',
        password: '',
        // 图片验证码
        captcha: '',
        // 手机号
        mobile: '',
        // 手机验证码
        code: '',
        rememberMe: true,
        // 绑定图片验证码的uid
        uid: '',
        // password代表密码, code代表验证码
        type: 'password'
      },
      loginRules: {
        username: [{ required: true, trigger: 'blur', message: '用户名不能为空' }],
        password: [{ required: true, trigger: 'blur', validator: validatePassword }],
        captcha: [{ required: true, trigger: 'blur', message: '验证码不能为空' }],
        mobile: [{ required: true, trigger: 'blur', validator: validateMobile }],
        code: [{ required: true, trigger: 'blur', message: '手机验证码不能为空' }]
      },
      sending: false,
      // 发送验证码点击后60s不能重复操作
      sendDisabled: false,
      // 定时
      timer: 0,
      // 密码框展示类型，密码还是文本
      passwordType: 'password',
      capsTooltip: false,
      loading: false,
      showDialog: false,
      redirect: undefined,
      otherQuery: {}
    }
  },
  computed: {
    sendButtonText() {
      if (this.timer === 0) {
        return '发送验证码'
      } else {
        return `${this.timer}秒后重发`
      }
    }
  },
  watch: {
    $route: {
      handler: function(route) {
        console.log(route)
        const query = route.query
        console.log(query)
        if (query) {
          this.redirect = query.redirect
          this.otherQuery = this.getOtherQuery(query)
          console.log(this.otherQuery)
        }
      },
      immediate: true
    },
    timer(num) {
      if (num > 0) {
        setTimeout(() => {
          this.timer = --num
        }, 1000)
      }
    }
  },
  created() {
    // window.addEventListener('storage', this.afterQRScan)
    this.handleCaptcha()
    // this.getCookie()
    const lastSendTime = Cookies.get('last-send-time')
    if (lastSendTime) {
      const timer = 60 - moment().diff(moment(lastSendTime).format('YYYY-MM-DD HH:mm:ss'), 'seconds')
      this.timer = timer > 0 ? timer : 0
    }
  },
  mounted() {
    if (this.loginForm.username === '') {
      this.$refs.username.focus()
    } else if (this.loginForm.password === '') {
      this.$refs.password.focus()
    }
  },
  destroyed() {
    // window.removeEventListener('storage', this.afterQRScan)
  },
  methods: {
    handleCaptcha() {
      this.loginForm.uid = UUIDv4()
      axios.get(process.env.VUE_APP_BASE_API + '/api/oauth/user/captcha', {
        params: { uid: this.loginForm.uid },
        responseType: 'blob'
      })
        .then(res => {
          // 响应的图片是blob二进制的
          this.codeUrl = URL.createObjectURL(new Blob([res.data], { type: 'image/jpeg' }))
        })
        .catch(error => {
          console.error('加载验证码失败:', error)
        })
    },
    handleSendSms() {
      this.$refs.loginForm.validateField(['mobile'], (errorMessage) => {
        if (!errorMessage) {
          this.sending = true
          const { mobile } = this.loginForm
          sendCode({ username: mobile })
            .then(() => {
              this.$message.success('验证码发送成功，请注意查收!')
              Cookies.set('last-send-time', new Date())
              this.timer = 60
            })
            .finally(() => (this.sending = false))

          Cookies.set('last-send-time', moment().format('YYYY-MM-DD HH:mm:ss'))
          this.timer = 60
        } else {
          console.error('校验失败：' + errorMessage)
          return false
        }
      })
    },
    getCookie() {
      const username = Cookies.get('username')
      const password = Cookies.get('password')
      const rememberMe = Cookies.get('rememberMe')
      this.loginForm = {
        username: username === undefined ? this.loginForm.username : username,
        password: password === undefined ? this.loginForm.password : password,
        rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
      }
    },
    checkCapslock(e) {
      const { key } = e
      this.capsTooltip = key && key.length === 1 && (key >= 'A' && key <= 'Z')
    },
    handleShowPwd() {
      if (this.passwordType === 'password') {
        this.passwordType = ''
      } else {
        this.passwordType = 'password'
      }
      this.$nextTick(() => {
        this.$refs.password.focus()
      })
    },
    handleLogin() {
      // 要校验的字段名
      let fields = []
      let submitData
      if (this.loginForm.type === 'code') {
        fields = fields.concat(['mobile', 'code'])
        submitData = { username: this.loginForm.mobile, code: this.loginForm.code, type: this.loginForm.type }
      } else {
        fields = fields.concat(['username', 'password', 'captcha'])
        submitData = { username: this.loginForm.username, password: this.loginForm.password, captcha: this.loginForm.captcha, rememberMe: this.loginForm.rememberMe, uid: this.loginForm.uid, type: this.loginForm.type }
      }
      // 创建一个数组来保存所有的校验Promise
      const validationPromises = fields.map(field => {
        return new Promise((resolve, reject) => {
          this.$refs.loginForm.validateField(field, (errorMessage) => {
            if (errorMessage) {
              // 如果有错误，reject该Promise并附上错误信息
              reject({ field, errorMessage })
            } else {
              // 没有错误，resolve该Promise
              resolve()
            }
          })
        })
      })

      // 使用Promise.all等待所有校验完成
      Promise.all(validationPromises)
        .then(() => {
          // 所有字段都通过了校验
          this.loading = true
          this.$store.dispatch('user/login', submitData)
            .then(() => {
              this.$message({
                showClose: true,
                message: '登录成功！',
                type: 'success',
                duration: 3000
              })
              this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
              this.loading = false
            })
            .catch(() => {
              this.loading = false
            })
        })
        .catch(error => {
          // 至少有一个字段校验失败
          console.error(`${error.field} 校验失败: ${error.errorMessage}`)
        })

      // this.$refs.loginForm.validateField(fields, valid => {
      //   console.log(valid)
      //   if (valid) {
      //     console.log(5555)
      //     this.loading = true
      //     console.log(this.loginForm)
      //     this.$store.dispatch('user/login', this.loginForm)
      //       .then(() => {
      //         this.$message({
      //           showClose: true,
      //           message: '登录成功！',
      //           type: 'success',
      //           duration: 3000
      //         })
      //         this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
      //         this.loading = false
      //       })
      //       .catch(() => {
      //         this.loading = false
      //       })
      //   } else {
      //     console.log(6666)
      //     console.log('error submit!!')
      //     return false
      //   }
      // })
    },
    getOtherQuery(query) {
      return Object.keys(query).reduce((acc, cur) => {
        if (cur !== 'redirect') {
          acc[cur] = query[cur]
        }
        return acc
      }, {})
    }
    // afterQRScan() {
    //   if (e.key === 'x-admin-oauth-code') {
    //     const code = getQueryObject(e.newValue)
    //     const codeMap = {
    //       wechat: 'code',
    //       tencent: 'code'
    //     }
    //     const type = codeMap[this.auth_type]
    //     const codeName = code[type]
    //     if (codeName) {
    //       this.$store.dispatch('LoginByThirdparty', codeName).then(() => {
    //         this.$router.push({ path: this.redirect || '/' })
    //       })
    //     } else {
    //       alert('第三方登录失败')
    //     }
    //   }
    // }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss">
  .login {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    background-image: url("../../assets/images/login-background3.jpg");
    //background-color: #0fc3ee;
    background-size: cover;
  }

  .title {
    margin: 0 auto 30px auto;
    text-align: center;
    color: #707070;
  }

  .login-form {
    border-radius: 6px;
    background: #ffffff;
    width: 400px;
    padding: 25px 25px 5px 25px;

    .el-input {
      height: 38px;

      input {
        height: 38px;
      }
    }

    .input-icon {
      height: 39px;
      width: 14px;
      margin-left: 2px;
    }
  }

  .login-tip {
    font-size: 13px;
    text-align: center;
    color: #bfbfbf;
  }

  .login-code {
    width: 33%;
    height: 38px;
    float: right;

    img {
      cursor: pointer;
      vertical-align: middle;
    }
  }

  .el-login-footer {
    height: 40px;
    line-height: 40px;
    position: fixed;
    bottom: 0;
    width: 100%;
    text-align: center;
    color: #fff;
    font-family: Arial,serif;
    font-size: 12px;
    letter-spacing: 1px;
  }

  .login-code-img {
    height: 38px;
  }

  .login_header {
    margin-bottom: 30px;
    text-align: center;
  }

  .login_header span {
    margin-right: 20px;
    cursor: pointer;
  }

  .active {
    color: #46a6ff;
    padding-bottom: 10px;
    border-bottom: 3px solid #46a6ff;
  }
</style>
